#include					"Map.hpp"

Map::Map(sf::RenderWindow &win)
	: _window(win), _turn(0), _win(false)
{
	_screenTexture.loadFromFile(GOBAN_PATH);
	_screen.setTexture(_screenTexture);
	_screen.setPosition(GOBAN_ORIGIN_COORD, GOBAN_ORIGIN_COORD);
	buildMap();
}


Map::~Map()
{


}

void						Map::init(char type)
{
	_gameType = (type >> 0) & 1;
	_arbitre = new Arbitre(_map, ((type >> 1) & 1), ((type >> 2) & 1));
	_players.push_back(new Human(_map, WHITE_STONE_PATH, *_arbitre));
	if (!_gameType)
		_players.push_back(new Human(_map, BLACK_STONE_PATH, *_arbitre));
	else
		_players.push_back(new IA(_map, BLACK_STONE_PATH, *_arbitre, 4));
}

void						Map::buildMap()
{	
	for (int y = GOBAN_FIRST_BOX_COORD; y <= GOBAN_LAST_BOX_COORD; y += INC)
		for (int x = GOBAN_FIRST_BOX_COORD; x <= GOBAN_LAST_BOX_COORD; x += INC)
			_map.insert(std::pair<int, Square*>(BOX_NUM(x, y), new Square(x, y)));
}

void						Map::draw()
{
	_window.draw(_screen);
	for (std::map<int, Square*>::iterator it = _map.begin(); it != _map.end(); ++it)
	{
		if ((*it).second->displayable())
			_window.draw((*it).second->getStone());
	}	
}

//							Function de Débug
void						Map::display()
{
	for (int i = 0; i < GOBAN_LAST_BOX_NUM; ++i)
	{
		std::cout << _map[i]->getSmell() << " ";
		if (!(i % GOBAN_BOX_PER_LINE))
			std::cout << std::endl;
	}
	std::cout << std::endl;
}

void						Map::spreadSmell(int key, int smellPower, short direction, bool color)
{
	if (KEY_VALIDITY(key))
		_map[key]->setSmell(smellPower, direction, color);
}

void						Map::smellManager(int key, int i, int length, bool color)
{
	/*
	Ici, on disperse "l'odeur" du pion au 8 cases environnantes sur un rayon de 5 case.
	Plus on s'eloigne du pion posé, plus le "smellpower" faiblis.
	Pour voir comment je stock tout ça, regarde la fonction setSmell dans le fichier Square.cpp
	Exemple : Si je pose un pion au milieu de la map, voila ce qu'il se passe
				////DISPERSION EN CARRE////
	0	0	0	0	0	0	0	0	0	0	0
	0	1	1	1	1	1	1	1	1	1	0
	0	1	2	2	2	2	2	2	2	1	0
	0	1	2	3	3	3	3	3	2	1	0
	0	1	2	3	4	4	4	3	2	1	0
	0	1	2	3	4	5	4	3	2	1	0
	0	1	2	3	4	4	4	3	2	1	0
	0	1	2	3	3	3	3	3	2	1	0
	0	1	2	2	2	2	2	2	2	1	0
	0	1	1	1	1	1	1	1	1	1 	0
	0	0	0	0	0	0	0	0	0	0	0

	if (i > 0)
		spreadSmell(key - (GOBAN_BOX_PER_LINE + 1), --i, (length + 2));
	else if (i == 0)
		return ;
	for (int j = 0; j < length; j++)
		{
			//Trouver moyen de checker les limites
			_map[key + j]->setSmell(i);
			_map[key + (j * GOBAN_BOX_PER_LINE)]->setSmell(i);
			_map[key + ((length - 1) * GOBAN_BOX_PER_LINE) + j]->setSmell(i);
			_map[key + (j * GOBAN_BOX_PER_LINE) + (length - 1)]->setSmell(i);
		}

				////DISPERSION EN ETOILE////
	0	0	0	0	0	0	0	0	0	0	0
	0  (1)	0	0	0  (1)	0	0	0  (1)	0
	0	0  (2)	0	0  (2)	0	0  (2)	0	0
	0	0	0  (3)	0  (3)	0  (3)	0	0	0
	0	0	0	0  (4) (4) (4)	0	0	0	0
	0  (1) (2) (3) (4) (5) (4) (3) (2) (1)	0
	0	0	0	0  (4) (4) (4)	0	0	0	0
	0	0	0  (3)	0  (3)	0  (3)	0	0	0
	0	0  (2)	0	0  (2)	0	0  (2)	0	0
	0  (1)	0	0	0  (1)	0	0	0  (1) 	0
	0	0	0	0	0	0	0	0	0	0	0
	*/
	for (int j = 1; j < i; j++)
	{
		spreadSmell((key + j), j, LEFT, color);
		spreadSmell((key - j), j, RIGHT, color);
		spreadSmell((key + (j * GOBAN_BOX_PER_LINE)), j, UP, color);
		spreadSmell((key - (j * GOBAN_BOX_PER_LINE)), j, DOWN, color);
		spreadSmell((key + (j * GOBAN_BOX_PER_LINE) - j), j, DIAG_UP_RIGHT, color);
		spreadSmell((key + (j * GOBAN_BOX_PER_LINE) + j), j, DIAG_UP_LEFT, color);
		spreadSmell((key - (j * GOBAN_BOX_PER_LINE) - j), j, DIAG_DOWN_RIGHT, color);
		spreadSmell((key - (j * GOBAN_BOX_PER_LINE) + j), j, DIAG_DOWN_LEFT, color);
	}
	//display();
}

void						Map::mouseMoveEvent(sf::Event::MouseMoveEvent &event)
{

}

bool						Map::mouseButtonEvent(sf::Event::MouseButtonEvent &event)
{
	int 					key = BOX_NUM(event.x, event.y);

	if (event.button == 1)
	{
		_arbitre->winState(-1);
		return (true);
	}
	if (COORD_VALIDITY(event.x) && COORD_VALIDITY(event.y))
	{
		if (!_map[key]->displayable() && KEY_VALIDITY(key))
		{
			std::cout << "Key => " << key << std::endl;
			_players[_turn++ % 2]->putStone(key);
			smellManager(key, 5, 0, (!((_turn) % 2)) ? false : true);
			if (_gameType)
				_players[_turn++ % 2]->putStone(0);
				////DISPERSION EN CARRE////
			//spreadSmell(key - (GOBAN_BOX_PER_LINE + 1), 5, 3);
						////DISPERSION EN ETOILE////
		}
	}
	return (true);
}

bool						Map::isThereAWinner()
{
	if (_arbitre->getWin())
		return (true);
	return (false);
}

std::string					Map::getWinner()
{
	std::cout << _turn % 2 << std::endl;
	return (WHO_WON(_turn % 2));
}